#include <iostream>
#include <assert.h>


char
single_code(char c)
{
  char uc = toupper(c);
  char sc;

  if (('A' > uc) || ('Z' < uc))
    {
      sc = '0';
    }

  switch (uc)
    {
    case 'A':
    case 'E':
    case 'I':
    case 'O':
    case 'U':
    case 'H':
    case 'W':
    case 'Y':
      {
	sc = '0';
	break;
      }

    case 'B':
    case 'F':
    case 'P':
    case 'V':
      {
	sc = '1';
	break;
      }

    case 'C':
    case 'G':
    case 'J':
    case 'K':
    case 'Q':
    case 'S':
    case 'X':
    case 'Z':
      {
	sc = '2';
	break;
      }

    case 'D':
    case 'T':
      {
	sc = '3';
	break;
      }

    case 'M':
    case 'N':
      {
	sc = '4';
	break;
      }

    case 'L':
      {
	sc = '5';
	break;
      }

    case 'R':
      {
	sc = '6';
	break;
      }
    }

  return sc;
}


std::string
soundex_code(const std::string& surname)
{
  assert (!surname.empty());

  std::string res;

  res += toupper(surname[0]);

  for (std::size_t i = 1; i < surname.length(); ++i)
    {
      char sc = single_code(surname[i]);
      if ((sc != '0') && (res[res.length() - 1] != sc))
	{
	  res += sc;
	}
    }

  std::size_t l = res.length();
  if (l > 4)
    {
      res.erase(4);
    }
  else if (l < 4)
    {
      for (std::size_t i = 0; i < 4 - l; ++i)
	{
	  res += '0';
	}
    }

  return res;
}


int main()
{
  std::string surname;
  
  while (true)
    {
      std::cout << "Enter surname (RETURN to quit): ";
      getline(std::cin, surname);
      if (surname.empty())
	{
	  break;
	}

      std::cout << "Soundex code for " << surname << " is " << soundex_code(surname) << std::endl;
    }
}
